package com.stars.easyms.logging.trace;

import com.stars.easyms.base.util.SpringBootUtil;
import org.aopalliance.aop.Advice;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.core.Ordered;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Modifier;

/**
 * <p>className: EasyMsLoggingPlumeLogTracePointcutAdvisor</p>
 * <p>description: EasyMsLogging的Trace切面管理类</p>
 *
 * @author guoguifang
 * @version 1.7.0
 * @date 2020/11/17 1:55 下午
 */
public final class EasyMsLoggingPlumeLogTracePointcutAdvisor extends AbstractPointcutAdvisor {

    private transient EasyMsLoggingPlumeLogTraceAspect advice;

    private transient Pointcut pointcut;

    public EasyMsLoggingPlumeLogTracePointcutAdvisor() {
        this.advice = new EasyMsLoggingPlumeLogTraceAspect();
        this.pointcut = new EasyMsLoggingTracePointcut();
        super.setOrder(Ordered.HIGHEST_PRECEDENCE + 10);
    }

    @Override
    public Pointcut getPointcut() {
        return this.pointcut;
    }

    @Override
    public Advice getAdvice() {
        return this.advice;
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if (other == null || this.getClass() != other.getClass()) {
            return false;
        }
        EasyMsLoggingPlumeLogTracePointcutAdvisor otherAdvisor = (EasyMsLoggingPlumeLogTracePointcutAdvisor) other;
        return (ObjectUtils.nullSafeEquals(this.advice, otherAdvisor.advice) &&
                ObjectUtils.nullSafeEquals(this.pointcut, otherAdvisor.pointcut));
    }

    @Override
    public int hashCode() {
        return 41 + this.advice.hashCode() * 41 + this.pointcut.hashCode() * 41;
    }

    private static class EasyMsLoggingTracePointcut implements Pointcut {

        @Override
        public ClassFilter getClassFilter() {
            return clazz -> !Modifier.isFinal(clazz.getModifiers())
                    && clazz.getName().startsWith(SpringBootUtil.getSpringApplicationPackageName());
        }

        @Override
        public MethodMatcher getMethodMatcher() {
            return MethodMatcher.TRUE;
        }
    }
}